package org.itzixi.service;


import cn.hutool.core.collection.CollStreamUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.itzixi.RedisKeyConstant;
import org.itzixi.mapper.FriendCircleLikedMapper;
import org.itzixi.mapper.FriendCircleMapper;
import org.itzixi.mapper.UsersMapper;
import org.itzixi.pojo.FriendCircle;
import org.itzixi.pojo.FriendCircleLiked;
import org.itzixi.pojo.Users;
import org.itzixi.pojo.bo.FriendCircleBO;
import org.itzixi.pojo.convertor.FriendCircleConvertor;
import org.itzixi.pojo.dto.FriendCircleDTO;
import org.itzixi.pojo.vo.CommentVO;
import org.itzixi.pojo.vo.FriendCircleVO;
import org.itzixi.utils.PagedGridResult;
import org.itzixi.utils.RedisOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FriendCircleService {

    private final FriendCircleMapper friendCircleMapper;

    private final UsersMapper usersMapper;

    private final FriendCircleLikedMapper friendCircleLikedMapper;

    private final PlatformTransactionManager platformTransactionManager;

    private final TransactionDefinition transactionDefinition;

    private final RedisOperator redis;

    private final CommentService commentService;


    /**
     * 发布朋友圈
     * @param friendCircleBO
     */
    public void publish(FriendCircleBO friendCircleBO) {
        FriendCircle friendCircle = FriendCircleConvertor.INSTANCE.friendCircleBOToEntity(friendCircleBO);
        friendCircleMapper.insert(friendCircle);
    }

    /**
     * 查询朋友圈列表
     * @param userId 用户id
     * @param pageInfo
     * @return
     */
    public PagedGridResult<FriendCircleVO> findByPage(String userId, Page<FriendCircleVO> pageInfo) {
        FriendCircleDTO friendCircleDTO = FriendCircleDTO.builder().userId(userId).build();
        pageInfo = friendCircleMapper.selectByPage(pageInfo, friendCircleDTO);
        List<FriendCircleVO> records = pageInfo.getRecords();
        if (CollectionUtils.isEmpty(records))
            return PagedGridResult.getPageInfo(pageInfo.getCurrent(), pageInfo.getSize(), pageInfo.getTotal(), new ArrayList<>());
        this.setLikedFriendsAndComments(records, userId);
        return PagedGridResult.getPageInfo(pageInfo.getCurrent(), pageInfo.getSize(), pageInfo.getTotal(), records);
    }

    /**
     * 查询点赞的好友
     * @param records
     */
    private void setLikedFriendsAndComments(List<FriendCircleVO> records, String userId){
        Set<String> fcIds = CollStreamUtil.toSet(records, FriendCircleVO::getFriendCircleId);
        List<FriendCircleLiked> friendCircleLikeds = this.queryLikedFriend(fcIds);
        // 查询所有的评论数量
        Collection<CommentVO> commentVOS = commentService.queryAll(fcIds);
        List<FriendCircleLiked> likedFriends = null;
        List<CommentVO> commentVOList = null;
        for (FriendCircleVO record : records) {
            likedFriends = new ArrayList<>();
            commentVOList = new ArrayList<>();
            String friendCircleId = record.getFriendCircleId();
            // 判断该条朋友圈是否被该用户点赞过
            String isLiked = redis.get(redis.buildKeys(RedisKeyConstant.REDIS_DOES_USER_LIKE_FRIEND_CIRCLE, friendCircleId, userId));
            for (FriendCircleLiked circleLiked : friendCircleLikeds) {
                if (Objects.equals(circleLiked.getFriendCircleId(), friendCircleId)){

                    likedFriends.add(circleLiked);
                }
            }

            for (CommentVO commentVO : commentVOS) {
                if (Objects.equals(commentVO.getFriendCircleId(), friendCircleId)){

                    commentVOList.add(commentVO);
                }
            }
            record.setCommentList(commentVOList);
            record.setLikedFriends(likedFriends);
            record.setDoILike(StringUtils.isNotBlank(isLiked));
        }
    }


    /**
     * 添加点赞记录
     * @param userId
     * @param friendCircleId
     */
    public void like(String userId, String friendCircleId) {
        TransactionStatus transaction = null;
        try {
            transaction = platformTransactionManager.getTransaction(transactionDefinition);
//            List<FriendCircleLiked> friendCircleLikeds = friendCircleLikedMapper.selectByFriendCircleIdAndLikedUserId(userId, friendCircleId);
//            if (CollectionUtils.isEmpty(friendCircleLikeds))
//                throw new RuntimeException("已经点赞过该条数据");

            FriendCircle friendCircle = friendCircleMapper.selectById(friendCircleId);
            Users users = usersMapper.selectById(userId);

            FriendCircleLiked friendCircleLiked = new FriendCircleLiked();
            friendCircleLiked.setFriendCircleId(friendCircleId);
            if (friendCircle != null){
                friendCircleLiked.setBelongUserId(friendCircle.getUserId());
            }
            friendCircleLiked.setLikedUserId(userId);
            if (users != null){
                friendCircleLiked.setLikedUserName(users.getNickname());
            }
            friendCircleLiked.setCreatedTime(LocalDateTime.now());
            friendCircleLikedMapper.insert(friendCircleLiked);

            // 点赞过该条朋友圈数量就增加1
            redis.increment(RedisKeyConstant.REDIS_FRIEND_CIRCLE_LIKED_COUNTS + friendCircleId, 1);
            // 标记哪个朋友点赞过该朋友圈
            redis.setnx(redis.buildKeys(RedisKeyConstant.REDIS_DOES_USER_LIKE_FRIEND_CIRCLE, friendCircleId, userId), userId);
            platformTransactionManager.commit(transaction);
        } catch (Exception e) {
            log.info("添加点赞记录报错：org.itzixi.service.FriendCircleService.like(),{},{}",e,e.getMessage());
            if (transaction != null)
                platformTransactionManager.rollback(transaction);
        }
    }

    public void unlike(String userId, String friendCircleId) {
        TransactionStatus transaction = null;
        try {
            transaction = platformTransactionManager.getTransaction(transactionDefinition);
            // 删除点赞记录
            friendCircleLikedMapper.deleteByFriendCircleIdAndLikedUserId(userId, friendCircleId);
            redis.decrement(RedisKeyConstant.REDIS_FRIEND_CIRCLE_LIKED_COUNTS + friendCircleId, 1);
            redis.del(redis.buildKeys(RedisKeyConstant.REDIS_DOES_USER_LIKE_FRIEND_CIRCLE, friendCircleId, userId));
            platformTransactionManager.commit(transaction);
        } catch (Exception e) {
            log.info("取消点赞报错：org.itzixi.service.FriendCircleService.unlike(),{},{}",e,e.getMessage());
            if (transaction != null)
                platformTransactionManager.rollback(transaction);

        }
    }


    public List<FriendCircleLiked> queryLikedFriend(Collection<String> friendCircleIds){
        QueryWrapper<FriendCircleLiked> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(FriendCircleLiked::getFriendCircleId, friendCircleIds);
        return friendCircleLikedMapper.selectList(queryWrapper);
    }

    public void delete(String friendCircleId, String userId) {
        QueryWrapper<FriendCircle> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda()
                        .eq(FriendCircle::getUserId, userId)
                        .eq(FriendCircle::getId, friendCircleId);
        friendCircleMapper.delete(deleteWrapper);
    }
}
